package de.luh.slimpp.generator

import de.luh.slimpp.slimPP.QualifiedName
import java.util.ArrayList
import java.util.HashMap
import java.util.List

class ScopeFinder<T> {
	val known = new HashMap<String, T>

	def put(List<String> names, T item) {
		known.put(names.join('.'), item)
	}

	def put(QualifiedName name, T item) {
		val names = new ArrayList<String>
		names.addAll(name.namespaces)
		names.add(name.name)
		put(names, item)
	}

	def find(List<String> names, List<String> fromScope) {
		val currentScope = new ArrayList<String>
		currentScope.addAll(fromScope)
		val allNames = names.join('.')

		// start the loop at 0 so that every scope plus the empty scope (which is
		// the global scope) is handled
		for (i : 0 .. currentScope.size) {
			val toFind = currentScope.join('', '.', '.', [it]) + allNames
			val found = known.get(toFind)
			if (found != null) {
				return found
			} else {
				if (!currentScope.empty) {
					currentScope.remove(currentScope.size - 1)
				}
			}
		}

		return null
	}

	def find(QualifiedName name, QualifiedName fromHere) {
		val names = new ArrayList<String>
		names.addAll(name.namespaces)
		names.addAll(name.name)

		val scope = new ArrayList<String>
		scope.addAll(fromHere.namespaces)

		find(names, scope)
	}

	def find(List<String> names, QualifiedName fromHere) {
		val scope = new ArrayList<String>
		scope.addAll(fromHere.namespaces)

		find(names, scope)
	}
}